package cn.wyl.user.service.impl;

import cn.wyl.basic.exception.BusinessException;
import cn.wyl.basic.util.Md5Utils;
import cn.wyl.basic.util.StrUtils;
import cn.wyl.basic.util.VerifyCodeConstants;
import cn.wyl.user.domain.Logininfo;
import cn.wyl.user.domain.User;
import cn.wyl.user.dto.UserDto;
import cn.wyl.user.mapper.LogininfoMapper;
import cn.wyl.user.mapper.UserMapper;
import cn.wyl.user.service.IUserService;
import cn.wyl.basic.service.impl.BaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

/**
 * 业务实现类：
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private UserMapper userMapper;

    /**
     * 通过手机号注册新用户
     * @param userDto
     */
    @Override
    public void registerByPhone(UserDto userDto) {
        //取出UserDto对象的属性
        String phone = userDto.getPhone();
        String phoneCode = userDto.getPhoneCode();
        String password = userDto.getPassword();
        String confirmpassword = userDto.getConfirmpassword();

        //1.校验
        //1.1.空值校验
        if (     StringUtils.isEmpty(phone)
                ||StringUtils.isEmpty(phoneCode)
                ||StringUtils.isEmpty(password)
                ||StringUtils.isEmpty(confirmpassword)
        ){
                throw new BusinessException("参数不能为空");
        }
        //1.2.两次密码是否相同
        if (!password.equals(confirmpassword)){
            throw new BusinessException("两次密码不一致!!!");
        }
        //1.3.验证码是否过期   redis存值格式：key[register:18708146200] : value[code:time]
        Object codeObj = redisTemplate.opsForValue().get(VerifyCodeConstants.REGISTER_CODE_PREFIX + phone);
        if (codeObj==null){
            throw new BusinessException("手机验证码过期，请重新获取");
        }
        //1.4.验证码是否正确  //  9527:1223555555
        String dbPhonecode =codeObj.toString().split(":")[0];
        if (!dbPhonecode.equalsIgnoreCase(phoneCode)){
            throw new BusinessException("验证码错误!!!");
        }

        //2.保存数据
        Logininfo logininfo= userDto2Logininfo(userDto);
        //先保存t_logininfo 自增id
        logininfoMapper.save(logininfo);
        //再保存t_user
        User user=logininfo2User(logininfo);
        userMapper.save(user);
    }





    //有了手机注册，可以不要添加了，手机注册就是添加,后台添加用户，同步添加到登录信息表
    @Transactional
    @Override
    public void save(User user) {
        //1.处理密码和盐值
        //获取随机盐值
        String salt = StrUtils.getComplexRandomString(32);
        //获取加密之后的密码
        String md5Pwd = Md5Utils.encrypByMd5(salt+user.getPassword());
        user.setSalt(salt);
        user.setPassword(md5Pwd);

        //根据user返回属性值相同的Logininfo并添加到数据库，返回Logininfo自增id
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.save(logininfo);
        //给user设置Logininfo_id外键并存入数据库
        user.setLogininfo_id(logininfo.getId());
        userMapper.save(user);
    }

    /**
     * 后台更新用户，同步更新到登录信息表
     * @param user
     */
    @Transactional
    @Override
    public void update(User user) {
        //1.处理密码和盐值
        //获取随机盐值
        String salt = StrUtils.getComplexRandomString(32);
        //获取加密之后的密码
        String md5Pwd = Md5Utils.encrypByMd5(salt+user.getPassword());
        //设置用户的盐值密码
        user.setSalt(salt);
        user.setPassword(md5Pwd);

        //根据用户转换成属性值相同的Logininfo
        Logininfo logininfo = user2Logininfo(user);

        //更新Logininfo和user
        logininfoMapper.update(logininfo);
        userMapper.update(user);
    }

    /**
     * 后台删除用户，关联删除 logininfo
     * @param id
     */
    @Transactional
    @Override
    public void remove(Long id) {
        //获取登录信息id
        Long logininfo_id = userMapper.loadById(id).getLogininfo_id();
        //删除登录信息对象
        logininfoMapper.remove(logininfo_id);
        //删除用户信息
        userMapper.remove(id);
    }


    private Logininfo user2Logininfo(User user) {
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user,logininfo);
        logininfo.setType(1);
        logininfo.setDisable(user.getState()==1?true:false);
        logininfo.setId(user.getLogininfo_id());
        return logininfo;
    }
    private Logininfo userDto2Logininfo(UserDto userDto) {
        Logininfo logininfo = new Logininfo();
        logininfo.setUsername(userDto.getPhone());
        logininfo.setPhone(userDto.getPhone());
        logininfo.setType(1);
        //获取随机盐值
        String salt = StrUtils.getComplexRandomString(32);
        //获取加密之后的密码
        String md5Pwd = Md5Utils.encrypByMd5(salt + userDto.getPassword());
        logininfo.setSalt(salt);
        logininfo.setPassword(md5Pwd);
        return logininfo;
    }

    private User logininfo2User(Logininfo logininfo) {
        User user = new User();
        //按照同名属性赋值
        BeanUtils.copyProperties(logininfo,user);
        user.setLogininfo_id(logininfo.getId());
        return user;
    }
}
